﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Data;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Diagnostics;

namespace Knowledgecast.Twitter.WPF
{
    public class StatusConverter : IValueConverter
    {
        string[] linkEndMarkers = new string[] { " ", ". ", ",", ": ", "!", "@ " };

        #region IValueConverter Members

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            List<Inline> inlines = null;
            string status = value as string;

            if (status != null)
            {
                inlines = new List<Inline>();

                if (status.Length > 0)
                {
                    int currentPos = 0;
                    int lastFoundPos = 0;
                    bool isProfileLink = false;

                    do
                    {
                        isProfileLink = false;
                        lastFoundPos = FindLinkStart(status, currentPos, out isProfileLink);

                        if (lastFoundPos >= 0)
                        {
                            int textLength = lastFoundPos - currentPos;
                            string text = status.Substring(currentPos, textLength);
                            inlines.Add(new Run(text));

                            int linkEndPos = FindStringEnd(status, lastFoundPos);
                            if (linkEndPos <= 0)
                            {
                                linkEndPos = status.Length;
                            }

                            int linkLength = linkEndPos - lastFoundPos;
                            string linkText = status.Substring(lastFoundPos, linkLength);

                            if (Uri.IsWellFormedUriString(linkText, UriKind.Absolute) || isProfileLink)
                            {
                                Hyperlink link = new Hyperlink();
                                link.Inlines.Add(new Run(linkText));                                

                                if (isProfileLink)
                                {
                                    string url = "http://www.twitter.com/" + linkText.Substring(1);
                                    link.NavigateUri = new Uri("http://www.twitter.com/" + linkText.Substring(1), UriKind.Absolute);
                                    link.Command = TwitterCommands.ShowUrl;
                                    link.CommandParameter = url;
                                }
                                else
                                {
                                    link.NavigateUri = new Uri(linkText, UriKind.Absolute);
                                    link.Command = TwitterCommands.ShowUrl;
                                    link.CommandParameter = linkText;
                                }

                                inlines.Add(link);
                            }
                            else
                            {
                                inlines.Add(new Run(linkText));
                            }

                            currentPos = lastFoundPos + linkLength;
                            if (currentPos >= status.Length)
                                break;
                        }
                    }
                    while (lastFoundPos >= 0);

                    if (currentPos < status.Length)
                    {
                        inlines.Add(new Run(status.Substring(currentPos)));
                    }
                }
            }

            return inlines;
        }

        int FindStringEnd(string text, int start)
        {
            int linkEndPos = -1;

            for (int i = 0; i < linkEndMarkers.Length; i++)
            {
                linkEndPos = text.IndexOf(linkEndMarkers[i], start);
                if (linkEndPos > 0)
                    break;
            }

            return linkEndPos;
        }

        int FindLinkStart(string text, int start, out bool isProfileLink)
        {
            isProfileLink = false;
            if (String.IsNullOrEmpty(text))
            {
                return -1;
            }

            int urlPos = -1;
            int profilePos = -1;
            urlPos = text.IndexOf("http://", start, StringComparison.CurrentCultureIgnoreCase);
            profilePos = text.IndexOf("@", start, StringComparison.CurrentCultureIgnoreCase);

            if (urlPos == -1 && profilePos == -1)
            {
                return -1;
            }
            else if (urlPos == -1)
            {
                isProfileLink = true;
                return profilePos;
            }
            else if(profilePos == -1)
            {
                return urlPos;
            }

            if (urlPos < profilePos)
            {
                return urlPos;
            }
            else if (profilePos < urlPos)
            {
                isProfileLink = true;
                return profilePos;                
            }
            else
            {
                return urlPos;
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }

        #endregion
    }
}
